package ph.com.gs3.formalistics.presenter;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import jim.h.common.android.zxinglib.integrator.IntentIntegrator;
import jim.h.common.android.zxinglib.integrator.IntentResult;

import org.json.JSONException;
import org.json.JSONObject;

import ph.com.gs3.formalistics.R;
import ph.com.gs3.formalistics.custom.interfaces.CustomDocumentActivity;
import ph.com.gs3.formalistics.global.constants.ActivityRequestCodes;
import ph.com.gs3.formalistics.global.constants.ActivityResultCodes;
import ph.com.gs3.formalistics.global.constants.DateTimePickerType;
import ph.com.gs3.formalistics.global.constants.DocumentType;
import ph.com.gs3.formalistics.global.constants.StarMark;
import ph.com.gs3.formalistics.global.interfaces.CallbackCommand;
import ph.com.gs3.formalistics.global.utilities.DateUtilities;
import ph.com.gs3.formalistics.global.utilities.ImageUtilities;
import ph.com.gs3.formalistics.global.utilities.logging.FLLogger;
import ph.com.gs3.formalistics.model.facades.DocumentsDataReader;
import ph.com.gs3.formalistics.model.facades.FormsDataReader;
import ph.com.gs3.formalistics.model.ldao.FilesLDAO;
import ph.com.gs3.formalistics.model.vo.application.SearchCondition;
import ph.com.gs3.formalistics.model.vo.business.User;
import ph.com.gs3.formalistics.model.vo.business.document.Document;
import ph.com.gs3.formalistics.model.vo.business.document.DocumentAction;
import ph.com.gs3.formalistics.model.vo.business.document.OutgoingAction;
import ph.com.gs3.formalistics.model.vo.business.document.SubmitReadyAction;
import ph.com.gs3.formalistics.model.vo.business.form.Form;
import ph.com.gs3.formalistics.model.vo.formcontent.EmbeddedViewData;
import ph.com.gs3.formalistics.model.vo.formcontent.PickListData;
import ph.com.gs3.formalistics.model.vo.parsers.json.PicklistDataJSONParser;
import ph.com.gs3.formalistics.model.vo.view.ViewColumn;
import ph.com.gs3.formalistics.presenter.fragements.workers.DocumentWorkerFragment;
import ph.com.gs3.formalistics.presenter.fragments.views.DocumentViewFragment;
import ph.com.gs3.formalistics.presenter.fragments.views.DocumentViewFragment.DocumentViewActionListener;
import ph.com.gs3.formalistics.presenter.fragments.views.DocumentViewFragment.DocumentViewFragmentParameterBundle;
import ph.com.gs3.formalistics.services.UploadService;
import ph.com.gs3.formalistics.view.dialogs.ListSelectionDialogFragment;
import ph.com.gs3.formalistics.view.document.DocumentDynamicViewContentsManager;
import ph.com.gs3.formalistics.view.document.DocumentViewContentsManager;
import ph.com.gs3.formalistics.view.document.specialfields.BarcodeScannerField;
import ph.com.gs3.formalistics.view.document.specialfields.BarcodeScannerField.BarcodeScannerListener;
import ph.com.gs3.formalistics.view.document.specialfields.DateTimePickerField;
import ph.com.gs3.formalistics.view.document.specialfields.DateTimePickerField.DateTimePickerListener;
import ph.com.gs3.formalistics.view.document.specialfields.DateTimePickerField.PickerType;
import ph.com.gs3.formalistics.view.document.specialfields.DynamicImageField;
import ph.com.gs3.formalistics.view.document.specialfields.DynamicImageField.DynamicImageFieldActionListener;
import ph.com.gs3.formalistics.view.document.specialfields.PickListField;
import ph.com.gs3.formalistics.view.document.specialfields.PickListField.PickListFieldListener;
import ph.com.gs3.formalistics.view.document.views.EmbeddedView;
import ph.com.gs3.formalistics.view.document.views.EmbeddedView.EmbeddedViewEventsListener;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.FragmentManager;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class DocumentActivity extends Activity implements DocumentViewActionListener,
        DateTimePickerListener, BarcodeScannerListener, PickListFieldListener,
        EmbeddedViewEventsListener, DynamicImageFieldActionListener {

	// ========================================================================
	// {{ Constants

	public static final String TAG = DocumentActivity.class.getSimpleName();

	public static final String EXTRA_CURRENT_USER = "current_user";
	public static final String EXTRA_DOCUMENT_TYPE = "document_type";
	public static final String EXTRA_FORM_ID = "form_id";
	public static final String EXTRA_DOCUMENT_ID = "document_id";
	public static final String EXTRA_OUTGOING_ACTION_ID = "outgoing_action_id";
	public static final String EXTRA_PARENT_DOCUMENT_ID = "parent_document_id";

	public static final String EXTRA_ISSUED_ACTION = "issued_action";

	// }}

	// ========================================================================
	// {{ Customization Interface

	public CustomDocumentActivity customDocumentActivity;

	// }}

	// ========================================================================
	// {{ Local State Fields

	private User currentUser;
	private int formId;
	private int documentId;
	private int parentDocumentId;
	private DocumentType documentType;

	private StarMark originalStarMark;

	// ==================================
	// Fields

	private String activeImageFieldId;
	private String activeBarcodeScannerFieldId;

	// }}

	private DocumentViewContentsManager documentViewContentsManager;

	private DocumentWorkerFragment documentWorkerFragment;
	private DocumentViewFragment documentViewFragment;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_document);

		initializeData();
		initializeWorkerFragment();

		// For custom implementations
		customDocumentActivity = CustomImplementation.getInstance().getCustomDocumentActivity(this,
		        currentUser);

		if (savedInstanceState == null) {

			Form form = documentWorkerFragment.getCurrentForm();
			Document document = documentWorkerFragment.getCurrentDocument();
			OutgoingAction outgoingAction = documentWorkerFragment.getOutgoingAction();

			DocumentViewFragmentParameterBundle bundle = new DocumentViewFragmentParameterBundle();

			bundle.currentUser = currentUser;
			bundle.form = form;
			bundle.document = document;
			bundle.documentType = documentType;
			bundle.outgoingAction = outgoingAction;

			if (customDocumentActivity != null) {
				documentViewContentsManager = customDocumentActivity
				        .getDocumentViewContentsManager(this, currentUser, form);
			}

			// In case the view is not supported but is set to be implemented, roll back
			// to dynamic view contents manager
			if (documentViewContentsManager == null) {
				documentViewContentsManager = new DocumentDynamicViewContentsManager(this,
				        currentUser);
			} else {
				FLLogger.w(TAG, "Unimplemented form view for form with web id " + form.getWebId());
			}

			bundle.documentViewContentsManager = documentViewContentsManager;

			documentViewFragment = DocumentViewFragment.createInstance(bundle);

			getFragmentManager().beginTransaction().add(R.id.container, documentViewFragment)
			        .commit();

			setTitle(form.getName());
		}

		if (documentType == DocumentType.EXISTING_DOCUMENT) {
			originalStarMark = documentWorkerFragment.getCurrentDocument().getStarMark();
		}

	}

	@Override
	public void onBackPressed() {

		// Block if there are child documents that will be orphaned

		boolean hasNewChildOutgoingActions = documentWorkerFragment.hasNewChildOutgoingActions();

		if (hasNewChildOutgoingActions && documentType != DocumentType.CHILD_DOCUMENT) {
			showClearChildOutgoingActionsOnExitDialog();
		} else {
			addFinishResults();
			super.onBackPressed();
		}
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		switch (id) {
			case R.id.action_submit_action: {
				onSubmitActionCommand();

				return true;
			}
		}

		return super.onOptionsItemSelected(item);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		switch (documentType) {
			case NEW_DOCUMENT:
			case CHILD_DOCUMENT:
				getMenuInflater().inflate(R.menu.document, menu);
				break;
			case EXISTING_DOCUMENT:
				Document document = documentWorkerFragment.getCurrentDocument();

				if (document.getProcessorId() == currentUser.getId()) {
					getMenuInflater().inflate(R.menu.document_for_approval, menu);
				} else {
					FLLogger.d(TAG, "not displaying for approval");
				}
				break;
			default:
				break;
		}

		return true;
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);

		if (data != null) {
			switch (requestCode) {
				case ActivityRequestCodes.PICK_DATE:
				case ActivityRequestCodes.PICK_TIME:
				case ActivityRequestCodes.PICK_DATE_TIME: {
					if (data.hasExtra(DateTimePickerActivity.EXTRA_RESULT_SELECTED_DATE)) {
						String fieldId = data
						        .getStringExtra(DateTimePickerActivity.EXTRA_DATE_TIME_PICKER_FIELD_ID);
						Date updatedDate = (Date) data
						        .getSerializableExtra(DateTimePickerActivity.EXTRA_RESULT_SELECTED_DATE);
						updateDateTimePickerView(requestCode, fieldId, updatedDate);
					}

				}
					break;

				case IntentIntegrator.REQUEST_CODE: { // Bar code scanner
					IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode,
					        resultCode, data);
					if (scanResult == null) {
						return;
					}
					final String result = scanResult.getContents();
					if (result != null) {
						Handler handler = new Handler();
						handler.post(new Runnable() {
							@Override
							public void run() {
								// custom events
								if (customDocumentActivity != null) {
									customDocumentActivity.onBarcodeScanned(
									        activeBarcodeScannerFieldId, result);
								}

								documentViewFragment.getDocumentViewContentsManager()
								        .setFieldValue(activeBarcodeScannerFieldId, result);
							}
						});

					}
				}
					break;
				case ActivityRequestCodes.PICKLIST: {

					if (data.hasExtra(PicklistPickerActivity.EXTRA_PICKED_RESULT)) {
						String fieldId = data.getStringExtra(PicklistPickerActivity.EXTRA_FIELD_ID);
						String result = data
						        .getStringExtra(PicklistPickerActivity.EXTRA_PICKED_RESULT);
						documentViewFragment.getDocumentViewContentsManager().setFieldValue(
						        fieldId, result);
					}

				}
					break;
				case ActivityRequestCodes.CAMERA_REQUEST: {

					// FIXME: Refactor - test only
					Bitmap image = (Bitmap) data.getExtras().get("data");

					FilesLDAO filesLDAO = new FilesLDAO(this);
					File storedFile = filesLDAO.storeImage(image);

					uploadFile(storedFile.getAbsolutePath());

					DynamicImageField dynamicImageField = (DynamicImageField) documentViewFragment
					        .getDocumentViewContentsManager().findFieldView(activeImageFieldId);

					dynamicImageField.setImage(image);

				}
					break;
				case ActivityRequestCodes.PICK_IMAGE: {

					// FIXME: Refactor - test only

					Uri selectedImageUri = data.getData();
					String imagePath = ImageUtilities.getRealPathFromURI(selectedImageUri, this);
					FLLogger.d(TAG, "Selected file: " + imagePath);

					uploadFile(imagePath);

					DynamicImageField dynamicImageField = (DynamicImageField) documentViewFragment
					        .getDocumentViewContentsManager().findFieldView(activeImageFieldId);

					dynamicImageField.setImagePath(imagePath);
				}
					break;
			}

		}

	}

	private void initializeData() {
		Bundle extras = getIntent().getExtras();

		currentUser = (User) extras.getSerializable(EXTRA_CURRENT_USER);
		documentType = (DocumentType) extras.get(EXTRA_DOCUMENT_TYPE);
		formId = extras.getInt(EXTRA_FORM_ID);
		documentId = extras.getInt(EXTRA_DOCUMENT_ID);

		if (extras.containsKey(EXTRA_PARENT_DOCUMENT_ID)) {
			parentDocumentId = extras.getInt(EXTRA_PARENT_DOCUMENT_ID);
		} else {
			parentDocumentId = -1;
		}

		FLLogger.d(TAG, "Parent document id: " + parentDocumentId);

	}

	private void initializeWorkerFragment() {

		FragmentManager fragmentMan = getFragmentManager();

		documentWorkerFragment = (DocumentWorkerFragment) fragmentMan
		        .findFragmentByTag(DocumentWorkerFragment.TAG);

		if (documentWorkerFragment == null) {

			// Initialize worker fragment
			documentWorkerFragment = DocumentWorkerFragment.createInstance(this, currentUser);
			fragmentMan.beginTransaction().add(documentWorkerFragment, DocumentViewFragment.TAG)
			        .commit();
		}

		documentWorkerFragment.initialize(documentType, formId, documentId, parentDocumentId);

	}

	// ========================================================================
	// {{ Functional Methods

	private void onSubmitActionCommand() {

		// Validate first if there are no
		// Document updatedDocument = documentViewFragment.updateDocumentValuesFromView();
		JSONObject updatedFieldValues = documentViewFragment.getUpdatedFieldValuesFromView();
		List<String> fieldsThatFailedValidation = documentWorkerFragment
		        .validateFields(updatedFieldValues);

		if (fieldsThatFailedValidation.isEmpty()) {
			showActionsDialog();
		} else {
			documentViewContentsManager.notifyFieldsRequired(fieldsThatFailedValidation);
			Toast.makeText(this, "Some fields have failed validation.", Toast.LENGTH_LONG).show();
		}

	}

	public void submitDocumentAction(String action) {

		// Extract data from document view
		// Document updatedDocument = documentViewFragment.updateDocumentValuesFromView();

		JSONObject updatedFieldValues = documentViewFragment.getUpdatedFieldValuesFromView();
		documentWorkerFragment.saveDocumentAction(updatedFieldValues, action);

		if (documentType != DocumentType.CHILD_DOCUMENT) {
			documentWorkerFragment.updateChildOutgoingActionsForSubmition();
		}

		Toast.makeText(
		        DocumentActivity.this,
		        "Your document is being processed. You may continue processing/viewing other documents while its sending.",
		        Toast.LENGTH_LONG).show();

		Intent resultIntent = new Intent();
		setResult(ActivityResultCodes.DOCUMENT_ACTION_SUBMITTED, resultIntent);
		finish();

	}

	private void updateDateTimePickerView(int sourceRequestCode, String fieldId, Date updatedDate) {

		if (updatedDate == null) {
			FLLogger.w(TAG, "No date selected");
		} else {
			SimpleDateFormat dateFormat;

			switch (sourceRequestCode) {
				case ActivityRequestCodes.PICK_DATE:
					dateFormat = DateUtilities.DEFAULT_DISPLAY_DATE_ONLY_FORMAT;
					break;
				case ActivityRequestCodes.PICK_TIME:
					dateFormat = DateUtilities.DEFAULT_DISPLAY_TIME_ONLY_FORMAT;
					break;
				case ActivityRequestCodes.PICK_DATE_TIME:
					dateFormat = DateUtilities.DEFAULT_DISPLAY_DATE_TIME_FORMAT;
					break;
				default: {
					FLLogger.w(TAG, "Invalid request code, the update was ignored");
					return;
				}

			}

			String displayDate = dateFormat.format(updatedDate);
			documentViewFragment.getDocumentViewContentsManager().setFieldValue(fieldId,
			        displayDate);

		}

	}

	private void addFinishResults() {
		Document document = documentWorkerFragment.getCurrentDocument();

		if (documentType == DocumentType.EXISTING_DOCUMENT
		        && originalStarMark != document.getStarMark()) {
			setResult(ActivityResultCodes.DOCUMENT_STAR_MARKED);
		}
	}

	// }}

	// ========================================================================
	// {{ Dialog View Methods

	private void showActionsDialog() {

		String dialogHeader = "Actions";
		String dialogEmptyListMessage = "No are actions available for this document";

		ListSelectionDialogFragment dialog = new ListSelectionDialogFragment(dialogHeader,
		        dialogEmptyListMessage);
		List<DocumentAction> actions;

		final Form currentForm = documentWorkerFragment.getCurrentForm();
		final Document currentDocument = documentWorkerFragment.getCurrentDocument();

		actions = new ArrayList<DocumentAction>();
		switch (documentType) {
			case NEW_DOCUMENT:
			case CHILD_DOCUMENT:
				actions = currentForm.getOnCreateActions();
				break;
			case EXISTING_DOCUMENT:
				actions = currentDocument.getActions();
				break;
			default:
				actions = new ArrayList<DocumentAction>();
		}

		List<String> actionStringList = new ArrayList<String>();

		for (DocumentAction action : actions) {
			actionStringList.add(action.getLabel());
		}

		dialog.setSelection(actionStringList);
		dialog.show(getFragmentManager(), ListSelectionDialogFragment.TAG);
		dialog.setOnItemSelectedCallback(new CallbackCommand<String>() {

			@Override
			public void execute(String result) {
				submitDocumentAction(result);
			}
		});
	}

	private void showClearChildOutgoingActionsOnExitDialog() {

		AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);

		dialogBuilder.setIcon(android.R.drawable.ic_dialog_alert);
		dialogBuilder.setTitle("Exit document?");
		dialogBuilder
		        .setMessage("You submitted new documents with this document as their parent, exiting now will delete all those documents. Are you sure you want to exit?");
		dialogBuilder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				documentWorkerFragment.clearOrphanedOutgoingActions();
				addFinishResults();
				finish();
			}

		});
		dialogBuilder.setNegativeButton("Cancel", null);
		dialogBuilder.show();
	}

	private void showDynamicImageOptionsDialog() {

		String dialogHeader = "Image";
		String dialogEmptyListMessage = "";
		List<String> selection = new ArrayList<>();

		selection.add("Take a Picture");
		selection.add("Browse");

		ListSelectionDialogFragment dialog = new ListSelectionDialogFragment(dialogHeader,
		        dialogEmptyListMessage);

		dialog.setSelection(selection);
		dialog.show(getFragmentManager(), ListSelectionDialogFragment.TAG);
		dialog.setOnItemSelectedCallback(new CallbackCommand<String>() {

			@Override
			public void execute(String result) {

				if ("Take a Picture".equals(result)) {
					Intent cameraIntent = new Intent(
					        android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
					startActivityForResult(cameraIntent, ActivityRequestCodes.CAMERA_REQUEST);
				} else {
					Intent intent = new Intent();
					intent.setType("image/*");
					intent.setAction(Intent.ACTION_GET_CONTENT);
					startActivityForResult(Intent.createChooser(intent, "Select Picture"),
					        ActivityRequestCodes.PICK_IMAGE);
				}

			}
		});

	}

	// }}

	// ========================================================================
	// {{ View Implementation

	@Override
	public void onMarkDocumentStarCommand(StarMark star) {

		documentWorkerFragment.markDocumentStar(star);

		if (star == StarMark.STARRED) {
			documentViewFragment.displayDocumentAsStarred();
		} else {
			documentViewFragment.displayDocumentAsUnstarred();
		}

	}

	@Override
	public void onOpenCommentsCommand() {

		Intent commentsActivity = new Intent(DocumentActivity.this, CommentsActivity.class);

		commentsActivity.putExtra(CommentsActivity.EXTRA_CURRENT_USER, currentUser);
		commentsActivity.putExtra(CommentsActivity.EXTRA_CURRENT_DOCUMENT_ID, documentId);

		startActivity(commentsActivity);
	}

	@Override
	public void onScanCodeCommand(BarcodeScannerField source) {
		activeBarcodeScannerFieldId = source.getFieldId();

		IntentIntegrator.initiateScan(DocumentActivity.this, R.layout.activity_zxing_capture,
		        R.id.viewfinder_view, R.id.preview_view, true);
	}

	@Override
	public void onOpenPickerViewCommand(DateTimePickerField source, PickerType pickerType,
	        String currentFieldValue) {
		DateTimePickerType viewPickerType = null;
		int requestCode = 0;

		switch (pickerType) {
			case DATE: {
				viewPickerType = DateTimePickerType.DATE_ONLY;
				requestCode = ActivityRequestCodes.PICK_DATE;
			}
				break;
			case TIME: {
				viewPickerType = DateTimePickerType.TIME_ONLY;
				requestCode = ActivityRequestCodes.PICK_TIME;
			}
				break;
			case DATETIME: {
				viewPickerType = DateTimePickerType.DATE_TIME;
				requestCode = ActivityRequestCodes.PICK_DATE_TIME;
			}
				break;
		}

		if (viewPickerType != null && requestCode != 0) {

			Intent dateTimePicker = new Intent(DocumentActivity.this, DateTimePickerActivity.class);

			dateTimePicker.putExtra(DateTimePickerActivity.EXTRA_DATE_TIME_PICKER_FIELD_ID,
			        source.getFieldId());
			dateTimePicker.putExtra(DateTimePickerActivity.EXTRA_DATE_TIME_PICKER_TYPE,
			        viewPickerType);
			dateTimePicker.putExtra(DateTimePickerActivity.EXTRA_PRE_SELECTED_DATE,
			        currentFieldValue);

			startActivityForResult(dateTimePicker, requestCode);
		}
	}

	@Override
	public void onOpenPicklistCommand(PickListField source) {
		PickListData data;

		try {
			data = PicklistDataJSONParser.parseJSON(source.getSourceFormField().getRawJSON());
		} catch (JSONException e) {

			// TODO: add an error report here that can be sent to the administrator of the
			// formalistics installation

			FLLogger.e(TAG, e.getMessage());
			Toast.makeText(
			        DocumentActivity.this,
			        "Failed to open picklist, its search data might be corrupted or has an incorrect entry. Contact your administrator.",
			        Toast.LENGTH_LONG).show();
			return;
		}

		Intent intent = new Intent(DocumentActivity.this, PicklistPickerActivity.class);
		intent.putExtra(PicklistPickerActivity.EXTRA_FIELD_ID, source.getFieldId());
		intent.putExtra(PicklistPickerActivity.EXTRA_CURRENT_USER, currentUser);
		intent.putExtra(PicklistPickerActivity.EXTRA_PICKLIST_SEARCH_AND_RESULT_DATA, data);
		startActivityForResult(intent, ActivityRequestCodes.PICKLIST);

	}

	@Override
	public void onCreateChildDocument(int formId) {

		Document currentDocument = documentWorkerFragment.getCurrentDocument();

		Intent documentActivity = new Intent(DocumentActivity.this, DocumentActivity.class);

		documentActivity.putExtra(DocumentActivity.EXTRA_CURRENT_USER, currentUser);
		documentActivity
		        .putExtra(DocumentActivity.EXTRA_DOCUMENT_TYPE, DocumentType.CHILD_DOCUMENT);
		documentActivity.putExtra(DocumentActivity.EXTRA_FORM_ID, formId);
		documentActivity.putExtra(DocumentActivity.EXTRA_DOCUMENT_ID, 0);
		documentActivity.putExtra(DocumentActivity.EXTRA_PARENT_DOCUMENT_ID,
		        currentDocument.getId());

		startActivityForResult(documentActivity, ActivityRequestCodes.OPEN_DOCUMENT);
	}

	@Override
	public void onSearchForEmbeddedViewRequested(String searchCompareToFieldValue,
	        EmbeddedView source) {

		EmbeddedViewData embeddedViewData = source.getEmbeddedViewData();

		FormsDataReader formsDataReader = new FormsDataReader(DocumentActivity.this, currentUser);
		DocumentsDataReader dataReader = new DocumentsDataReader(DocumentActivity.this);

		Form searchForm = formsDataReader.getForm(embeddedViewData.getSearchFormId());
		String searchFieldName = embeddedViewData.getSearchFieldId();
		String operator = embeddedViewData.getSearchConditionalOperator();
		SearchCondition condition = new SearchCondition(searchFieldName, operator,
		        searchCompareToFieldValue);

		List<SearchCondition> searchConditions = new ArrayList<>();
		searchConditions.add(condition);

		List<ViewColumn> searchViewColumns = embeddedViewData.getViewColumns();
		List<String> searchColumnNames = new ArrayList<>();

		for (ViewColumn column : searchViewColumns) {
			searchColumnNames.add(column.getName());
		}

		List<JSONObject> listData = dataReader.search(searchForm, searchColumnNames,
		        currentUser.getId(), searchConditions);

		source.setData(listData);

	}

	@Override
	public void onOpenDocumentCommand(int formId, int documentId) {
		FLLogger.d(TAG, "onOpenDocumentCommand: " + formId + " " + documentId);

		Intent documentActivity = new Intent(DocumentActivity.this, DocumentActivity.class);

		documentActivity.putExtra(DocumentActivity.EXTRA_CURRENT_USER, currentUser);
		documentActivity.putExtra(DocumentActivity.EXTRA_DOCUMENT_TYPE,
		        DocumentType.EXISTING_DOCUMENT);
		documentActivity.putExtra(DocumentActivity.EXTRA_FORM_ID, formId);
		documentActivity.putExtra(DocumentActivity.EXTRA_DOCUMENT_ID, documentId);

		startActivityForResult(documentActivity, ActivityRequestCodes.OPEN_DOCUMENT);

	}

	// }}

	@Override
	public void onOpenIssuedOutgoingActionCommand() {

		Intent documentActivity = new Intent(DocumentActivity.this, DocumentActivity.class);

		documentActivity.putExtra(DocumentActivity.EXTRA_CURRENT_USER, currentUser);
		documentActivity.putExtra(DocumentActivity.EXTRA_DOCUMENT_TYPE,
		        DocumentType.OUTGOING_DOCUMENT);
		documentActivity.putExtra(DocumentActivity.EXTRA_FORM_ID, formId);
		documentActivity.putExtra(DocumentActivity.EXTRA_DOCUMENT_ID, documentId);

		startActivity(documentActivity);
	}

	@Override
	public void onViewReady() {
		OutgoingAction outgoingAction = documentWorkerFragment.getOutgoingAction();

		boolean showPrompt = outgoingAction != null
		        && documentType == DocumentType.EXISTING_DOCUMENT
		        && !outgoingAction.getAction().equals(
		                SubmitReadyAction.ACTION_NO_DOCUMENT_SUBMISSION);

		documentViewFragment.showOutgoingActionsPropmt(showPrompt);

		// Invoke document view contents manager events
		documentViewContentsManager.onLoad();

	}

	@Override
	public void onSelectImage(DynamicImageField source) {

		activeImageFieldId = source.getFieldId();
		showDynamicImageOptionsDialog();

	}

	// =========================================================================
	// Test Only

	private void uploadFile(String fileURI) {

		FLLogger.d(TAG, "Now uploading file ");

		Intent intent = new Intent(DocumentActivity.this, UploadService.class);
		intent.addCategory(Intent.CATEGORY_DEFAULT);
		intent.putExtra(UploadService.EXTRA_OWNER, currentUser);
		intent.putExtra(UploadService.EXTRA_FILE_URI, fileURI);
		startService(intent);

	}

}
